package cn.demoncat.util.webservice;

import cn.demoncat.util.exception.BizErrorRuntimeException;
import cn.demoncat.util.lang.JsonUtil;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;

import javax.xml.namespace.QName;

/**
 * WebService CXF 客户端
 *
 * @author 延晓磊
 * @since 2021年08月19日
 */
public class CxfClientUtil {

    /**
     * 创建Service代理对象（生成并拷贝服务端wsdl代码）
     *
     * @param serviceClass
     * @param wsdl
     * @param user
     * @param pwd
     * @return
     */
    public static <S>S build(Class<S> serviceClass, String wsdl, String user, String pwd) {
        // 构建Service
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(serviceClass);
        factory.setAddress(wsdl);
        factory.setUsername(user);
        factory.setPassword(pwd);
        Object service =  factory.create();
        // 客户端设置
        Client proxy = ClientProxy.getClient(service);
        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
        HTTPClientPolicy policy = new HTTPClientPolicy();
        policy.setConnectionTimeout(120_000);
        policy.setReceiveTimeout(1800_000);
        conduit.setClient(policy);
        // 返回Service
        return (S)service;
    }

    /**
     * 发起请求（动态调用）
     *
     * @param wsdl          WSDL地址
     * @param namespace     Namespace URI of the QName
     * @param method        请求方法
     * @param params        请求参数
     */
    public static String request(String wsdl, String namespace, String method, Object ... params) {
        // 构建客户端
        JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
        Client client = factory.createClient(wsdl);
        // 命名空间
        QName qname = new QName(namespace, method);
        try {
            return JsonUtil.toString(client.invoke(qname, params)[0]);
        } catch (Exception e) {
            throw new BizErrorRuntimeException("发起CXF请求失败", e);
        }
    }

}
